package com.sinochem.sales.common.bean;

import com.sinochem.sales.common.constant.SecurityConstants;
import com.sinochem.sales.common.entity.Result;
import com.sinochem.sales.common.exception.BusinessException;
import com.sinochem.sales.common.util.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author xuan😴🐶🐱🐽🌺  <a href="zhangshixuanj@163.com">联系作者</a>
 * @version Revision:v1.0,Date: 2018/4/13 10:02
 * @project cloud
 * @description Controller 增强
 * @Modification Date: 2018/4/16 11:01  {填写修改说明}
 */
@Slf4j
@Aspect
@Component
public class ControllerAop {

    @Pointcut("execution(public com.sinochem.sales.common.entity.Result *(..))")
    public void pointCutR() {
    }


    @Around("pointCutR()")
    public Object methodRHandler(ProceedingJoinPoint pjp) {
        return methodHandler(pjp);
    }


    private Object methodHandler(ProceedingJoinPoint pjp) {
        long startTime = System.currentTimeMillis();

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        String UID = request.getHeader(SecurityConstants.UID_HEADER);
        String username = request.getHeader(SecurityConstants.USER_HEADER);
        if (StringUtils.isNotBlank(username)) {
            log.info("Controller AOP get username:{}", username);
            log.info("Controller AOP get UID:{}", UID);
            UserUtils.setUser(username);
            UserUtils.setUID(UID);
        }

        log.info("URL : " + request.getRequestURL().toString());
        log.info("HTTP_METHOD : " + request.getMethod());
        log.info("IP : " + request.getRemoteAddr());
        log.info("CLASS_METHOD : " + pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName());
        log.info("ARGS : " + Arrays.toString(pjp.getArgs()));

        Object result;


        try {
            result = pjp.proceed();
            log.info(pjp.getSignature() + "use time:" + (System.currentTimeMillis() - startTime));
        } catch (BusinessException e) {
            throw new BusinessException(e.getResult());
        } catch (Throwable e) {
            throw new BusinessException(Result.error("请稍后再试"));
        } finally {
            if (StringUtils.isNotEmpty(UID)) {
                UserUtils.clearAllUserInfo();
            }
        }

        return result;
    }
}
